package com.groupseven.backend.configuration.WebLog;

import com.alibaba.fastjson.JSON;
import com.groupseven.backend.domain.Log.OperationLog;
import com.groupseven.backend.domain.User.User;
import com.groupseven.backend.services.OperationLogService;
import com.groupseven.backend.util.HttpContextUtil;
import com.groupseven.backend.util.IPUtils;
import com.groupseven.backend.util.ShiroUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Component
// lombok 的日志注解
@Slf4j
// 该注解 标识这是个aop类
@Aspect
public class WebLogAspect {
    @Autowired
    OperationLogService operationLogService;
    /**
     * 切入被该注解标志的方法切入
     */
    @Pointcut("@annotation(com.groupseven.backend.configuration.WebLog.WebLog)")
    public void logPointcut() {

    }

    /**
     * 前置切入
     */
    /**@Before("logPointcut()")
    public void doBefore(JoinPoint jp) {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
    .getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    System.out.println();
    log.info("请求路径：" + request.getRequestURL().toString());
    log.info("请求类型:" + request.getMethod());
    Enumeration<String> enu = request.getParameterNames();
    log.info("Request Args   : {}", new Gson().toJson(jp.getArgs()));
    while (enu.hasMoreElements()) {
    String name = enu.nextElement();
    log.info("属性名:{},属性值:{}", name, request.getParameter(name));
    }
    }**/
    /**
     * 后置切入
     */
    @AfterReturning("logPointcut()")
    public void saveOperationLog(JoinPoint joinPoint) {
        System.out.println("切面。。。。。");
        //保存日志
        OperationLog operationLog = new OperationLog(null,null,null,null,null,null);

        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();

        //获取操作
        WebLog webLog = method.getAnnotation(WebLog.class);
        if (webLog != null) {
            String value = webLog.operateType();
            operationLog.setOperation(value);//保存获取的操作
        }

        //获取请求的类名
        String className = joinPoint.getTarget().getClass().getName();
        //获取请求的方法名
        String methodName = method.getName();
        operationLog.setMethod(className + "." + methodName);

        //请求的参数
        Object[] args = joinPoint.getArgs();
        //将参数所在的数组转换成json
        String canshu = JSON.toJSONString(args);
        operationLog.setCanshu(canshu);

        operationLog.setCreateDate(new Date());
        //获取用户名
        try {
            User user = (User) ShiroUtils.getSubject().getPrincipal();
            operationLog.setUsername(user.getUsername());
            //获取用户ip地址
            HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
            operationLog.setIp(IPUtils.IpUtils.getIpAddr(request));

            //调用service保存SysLog实体类到数据库
            operationLogService.insertOperationLog(operationLog);
        } catch (Exception e) {
            System.out.println("切面里发生了错误！");
        }
    }




/**
 @AfterReturning(returning = "obj", pointcut = "logPointcut()")
 public void doAfter(Object obj) {

 }
 **/
    /**
     * 环绕切入

     @Around("logPointcut()")
     public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
     long startTime = System.currentTimeMillis();
     Object result = proceedingJoinPoint.proceed();
     // 打印出参
     log.info("调用结束.... 返回值: {}", new Gson().toJson(result));
     // 执行耗时
     log.info("耗时: {} ms", System.currentTimeMillis() - startTime);
     return result;
     }
     */
}
